<!doctype html>



  


<html class="theme-next pisces use-motion">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="webpack,打包工具," />





  <link rel="alternate" href="/atom.xml" title="前端-洋洋" type="application/atom+xml" />




  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />






<meta name="description" content="最近在看许多React的资料，发现了大部分的项目都是用webpack行模块化管理的工具。这次也是借着写了一个React-Todos的小应用，对webPack最基本实用的功能体验了一番，顺带做个小记录。
为什么用webpackCommonJs与AMD在一开始，我们先讲一下它和以往我们所用的模块管理工具有什么不一样。在最开始的阶段，Js并没有这些模块机制，各种Js到处飞，得不到有效妥善的管理。后来前端">
<meta property="og:type" content="article">
<meta property="og:title" content="webpack前端模块加载工具">
<meta property="og:url" content="http://html-js.site/2016/05/30/webpack前端模块加载工具/index.html">
<meta property="og:site_name" content="前端-洋洋">
<meta property="og:description" content="最近在看许多React的资料，发现了大部分的项目都是用webpack行模块化管理的工具。这次也是借着写了一个React-Todos的小应用，对webPack最基本实用的功能体验了一番，顺带做个小记录。
为什么用webpackCommonJs与AMD在一开始，我们先讲一下它和以往我们所用的模块管理工具有什么不一样。在最开始的阶段，Js并没有这些模块机制，各种Js到处飞，得不到有效妥善的管理。后来前端">
<meta property="og:image" content="http://html-js.site/images/page/webpack/1.jpg">
<meta property="og:updated_time" content="2016-06-08T06:13:46.252Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="webpack前端模块加载工具">
<meta name="twitter:description" content="最近在看许多React的资料，发现了大部分的项目都是用webpack行模块化管理的工具。这次也是借着写了一个React-Todos的小应用，对webPack最基本实用的功能体验了一番，顺带做个小记录。
为什么用webpackCommonJs与AMD在一开始，我们先讲一下它和以往我们所用的模块管理工具有什么不一样。在最开始的阶段，Js并没有这些模块机制，各种Js到处飞，得不到有效妥善的管理。后来前端">
<meta name="twitter:image" content="http://html-js.site/images/page/webpack/1.jpg">



<script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Pisces',
    sidebar: {"position":"left","display":"post"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: 0,
      author: '博主'
    }
  };
</script>




  <link rel="canonical" href="http://html-js.site/2016/05/30/webpack前端模块加载工具/"/>

  <title> webpack前端模块加载工具 | 前端-洋洋 </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  



  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "//hm.baidu.com/hm.js?ca98d1db5559cb59848d14443c7fa5dd";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>








  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">前端-洋洋</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle">专注于前端</p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                webpack前端模块加载工具
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            <span class="post-meta-item-icon">
              <i class="fa fa-calendar-o"></i>
            </span>
            <span class="post-meta-item-text">发表于</span>
            <time itemprop="dateCreated" datetime="2016-05-30T19:34:21+08:00" content="2016-05-30">
              2016-05-30
            </time>
          </span>

          

          
            
              <span class="post-comments-count">
                &nbsp; | &nbsp;
                <a href="/2016/05/30/webpack前端模块加载工具/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count ds-thread-count" data-thread-key="2016/05/30/webpack前端模块加载工具/" itemprop="commentsCount"></span>
                </a>
              </span>
            
          

          

          
          

          
        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>最近在看许多React的资料，发现了大部分的项目都是用webpack行模块化管理的工具。这次也是借着写了一个React-Todos的小应用，对webPack最基本实用的功能体验了一番，顺带做个小记录。</p>
<h3 id="为什么用webpack"><a href="#为什么用webpack" class="headerlink" title="为什么用webpack"></a>为什么用webpack</h3><h3 id="CommonJs与AMD"><a href="#CommonJs与AMD" class="headerlink" title="CommonJs与AMD"></a>CommonJs与AMD</h3><p>在一开始，我们先讲一下它和以往我们所用的模块管理工具有什么不一样。在最开始的阶段，Js并没有这些模块机制，各种Js到处飞，得不到有效妥善的管理。后来前端圈开始制定规范，最耳熟能详的是CommonJs和AMD。</p>
<p>CommonJs是应用在NodeJs，是一种同步的模块机制。它的写法大致如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">var firstModule = require(&quot;firstModule&quot;);</span><br><span class="line"></span><br><span class="line">//your code...</span><br><span class="line"></span><br><span class="line">module.export = anotherModule</span><br></pre></td></tr></table></figure></p>
<p>AMD的应用场景则是浏览器，异步加载的模块机制。require.js的写法大致如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">define([&apos;firstModule&apos;], function(module)&#123;</span><br><span class="line">  </span><br><span class="line">  //your code...</span><br><span class="line">  return anotherModule</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></p>
<p>其实我们单比较写法，就知道CommonJs是更为优秀的。它是一种同步的写法，对Human友好，而且代码也不会繁琐臃肿。但更重要的原因是， 随着npm成为主流的JavaScript组件发布平台，越来越多的前端项目也依赖于npm上的项目，或者自身就会发布到npm平台。 所以我们对如何可以使用npm包中的模块是我们的一大需求。所以browserify工具就出现了，它支持我们直接使用 require() 的同步语法去加载npm模块。</p>
<p>当然我们这里不得不说的是，ES2015（ES6）里也有了自己的模块机制，也就是说ES6的模块机制是官方规定的，我们通过 <a href="https://babeljs.io/" rel="external" target="_blank">babel</a> （一种6to5的编译器）可以使用比较多的新特性了，包括我们提到的模块机制，而它的写法大致如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">import &#123;someModule&#125; from &quot;someModule&quot;;</span><br><span class="line"></span><br><span class="line">// your codes...</span><br><span class="line"></span><br><span class="line">export anotherModule;</span><br></pre></td></tr></table></figure></p>
<p>当然上面的写法只是最基本的，还有其他的不同加载模块的写法，可以看一下阮一峰老师的 <a href="http://es6.ruanyifeng.com/#docs/class" rel="external" target="_blank">ECMAScript 6 入门</a> 或者babel的相关文档 <a href="https://babeljs.io/docs/learn-es2015/#modules" rel="external" target="_blank">Learn ES2015</a> 。</p>
<h3 id="功能特性"><a href="#功能特性" class="headerlink" title="功能特性"></a>功能特性</h3><h4 id="browserify的出现非常棒，但webpack更胜一筹"><a href="#browserify的出现非常棒，但webpack更胜一筹" class="headerlink" title="browserify的出现非常棒，但webpack更胜一筹"></a>browserify的出现非常棒，但webpack更胜一筹</h4><p>我们来看看webpack支持哪些功能特性：</p>
<ul>
<li>支持CommonJs和AMD模块，意思也就是我们基本可以无痛迁移旧项目。</li>
<li>支持模块加载器和插件机制，可对模块灵活定制。特别是我最爱的babel-loader，有效支持ES6。</li>
<li>可以通过配置，打包成多个文件。有效利用浏览器的缓存功能提升性能。</li>
<li>将样式文件和图片等静态资源也可视为模块进行打包。配合loader加载器，可以支持sass，less等CSS预处理器。</li>
<li>内置有source map，即使打包在一起依旧方便调试。</li>
</ul>
<p>看完上面这些，可以想象它就是一个前端工具，可以让我们进行各种模块加载，预处理后，再打包。之前我们对这些的处理是放在grunt或gulp等前端自动化工具中。有了webpack，我们无需借助自动化工具对模块进行各种处理，让我们工具的任务分的更加清晰。</p>
<p>我们看一下官方对webpack理解的图。<br><img src="/images/page/webpack/1.jpg"><br>任何静态资源都可以视作模块，然后模块之间也可以相互依赖，通过webpack对模块进行处理后，可以打包成我们想要的静态资源。</p>
<p>既然已经大致知道为什么我们要使用webpack了，我们接下来就开始使用webpack吧！</p>
<h3 id="开始使用webpack"><a href="#开始使用webpack" class="headerlink" title="开始使用webpack"></a>开始使用webpack</h3><p>首先新建一个webpack101的项目，我们将在webpack101这里开展我们接下来的各项学习<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$ npm init // 用于初始化项目的package.json</span><br><span class="line"></span><br><span class="line">//初始化文件目录：</span><br><span class="line">webpack101</span><br><span class="line">  --- src</span><br><span class="line">    --- entry.js</span><br><span class="line">    --- module1.js</span><br><span class="line">  --- index.html</span><br><span class="line">  --- package.json</span><br><span class="line">  --- webpack.config.js</span><br></pre></td></tr></table></figure></p>
<h3 id="安装webpack"><a href="#安装webpack" class="headerlink" title="安装webpack"></a>安装webpack</h3><p>我们通过npm来将webpack安装到全局<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install webpack -g</span><br></pre></td></tr></table></figure></p>
<h3 id="一个最简单的webpack"><a href="#一个最简单的webpack" class="headerlink" title="一个最简单的webpack"></a>一个最简单的webpack</h3><h4 id="webpack配置"><a href="#webpack配置" class="headerlink" title="webpack配置"></a>webpack配置</h4><p>webpack是需要进行配置的，我们在使用webpack的时候，会默认 webpack.config.js 为我们的配置文件。所以接下来，我们新建这个js文件。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">// webpack.config.js</span><br><span class="line">var path = require(&quot;path&quot;);</span><br><span class="line">module.exports = &#123;</span><br><span class="line">  entry: &apos;../src/entry.js&apos;, //演示单入口文件</span><br><span class="line">  output: &#123;</span><br><span class="line">    path: path.join(__dirname, &apos;out&apos;),  //打包输出的路径</span><br><span class="line">    filename: &apos;bundle.js&apos;,			  //打包后的名字</span><br><span class="line">    publicPath: &quot;./out/&quot;				//html引用路径，在这里是本地地址。</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<h3 id="编写入口文件"><a href="#编写入口文件" class="headerlink" title="编写入口文件"></a>编写入口文件</h3><p>接下来就编写我们的入口文件 entry.js 和第一个模块文件 module1.js 。我们一切从简，里面只用来加载一个Js模块。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// entry.js</span><br><span class="line">require(&quot;./module1&quot;); // 使用CommonJs来加载模块</span><br></pre></td></tr></table></figure></p>
<p>下一个文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">// module1.js</span><br><span class="line">console.log(&quot;Hello Webpack!&quot;);</span><br></pre></td></tr></table></figure></p>
<h3 id="启动webpack"><a href="#启动webpack" class="headerlink" title="启动webpack"></a>启动webpack</h3><p>一切准备好后，我们仅需要在项目根目录下，用命令行 webpack 执行一下即可。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// webpack 命令行的几种基本命令</span><br><span class="line"></span><br><span class="line">$ webpack // 最基本的启动webpack方法</span><br><span class="line">$ webpack -w // 提供watch方法，实时进行打包更新</span><br><span class="line">$ webpack -p // 对打包后的文件进行压缩，提供production</span><br><span class="line">$ webpack -d // 提供source map，方便调试。</span><br></pre></td></tr></table></figure></p>
<p>webpack成功运行后，我们就可以看到根目录出现了out文件夹，里面有我们打包生成的 bundle.js 。我们最后通过在 index.html 里对这个文件引入就可以了。我们可以在控制台看到我们想要的结果， <b>Hello Webpack !</b></p>
<h3 id="多模块依赖"><a href="#多模块依赖" class="headerlink" title="多模块依赖"></a>多模块依赖</h3><p>刚才的例子，我们仅仅是跑通了webpack通过 entry.js 入口文件进行打包的例子。下面我们就来看一下它是否真的支持CommonJs和AMD两种模块机制呢？下面我们新建多几个js文件吧！<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// 修改module1.js</span><br><span class="line">require([&quot;./module3&quot;], function()&#123;</span><br><span class="line">  console.log(&quot;Hello Webpack!&quot;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>下一个文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// module2.js，使用的是CommonJs机制导出包</span><br><span class="line">module.exports = function(a, b)&#123;</span><br><span class="line">  return a + b;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>下一个文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// module3.js，使用AMD模块机制</span><br><span class="line">define([&apos;./module2.js&apos;], function(sum)&#123;</span><br><span class="line">  return console.log(&quot;1 + 2 = &quot; + sum(1, 2));</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure></p>
<p>其实像上面这样混用两种不同机制非常不好，这里仅仅是展示用的，在开发新项目时还是推荐CommonJs或ES2015的Module。当然我个人更倾向于ES2015的模块机制的～</p>
<h3 id="loader加载器"><a href="#loader加载器" class="headerlink" title="loader加载器"></a>loader加载器</h3><p>到了我最喜欢也是最激动人心的功能了！我们先想想应用场景，前端社区有许多预处理器供我们使用。我们可以使用这些预处理器做一些强大的事情，大家都听过的就是 CoffeeScript 和 Sass 了。我们以前要编译这些预处理器，就是用 gulp 进行编译。但是我们对这些文件处理其实也挺繁琐的，webpack可以一次性解决！</p>
<p>在这里我们用Sass和babel编译ES2015为例子，看一下loader是如何使用的。</p>
<h3 id="安装loader"><a href="#安装loader" class="headerlink" title="安装loader"></a>安装loader</h3><p>我们第一步就是先要安装好各个必须的loader，我们直接看看需要通过npm安装什么。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install style-loader css-loader url-loader babel-loader sass-loader file-loader --save-dev</span><br></pre></td></tr></table></figure></p>
<h3 id="配置loader"><a href="#配置loader" class="headerlink" title="配置loader"></a>配置loader</h3><p>安装完各个loader后，我们就需要配置一下我们的 webpack.config.js ，载入我们的loader。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">// webpack.config.js</span><br><span class="line">module.exports = &#123;</span><br><span class="line">  entry: path.join(__dirname, &apos;src/entry.js&apos;),</span><br><span class="line">  output: &#123;</span><br><span class="line">    path: path.join(__dirname, &apos;out&apos;),</span><br><span class="line">    publicPath: &quot;./out/&quot;,</span><br><span class="line">    filename: &apos;bundle.js&apos;</span><br><span class="line">  &#125;,</span><br><span class="line">  // 新添加的module属性</span><br><span class="line">  module: &#123;</span><br><span class="line">    loaders: [</span><br><span class="line">      &#123;test: /\.js$/, loader: &quot;babel&quot;&#125;,</span><br><span class="line">      &#123;test: /\.css$/, loader: &quot;style!css&quot;&#125;,</span><br><span class="line">      &#123;test: /\.(jpg|png)$/, loader: &quot;url?limit=8192&quot;&#125;,</span><br><span class="line">      &#123;test: /\.scss$/, loader: &quot;style!css!sass&quot;&#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<p>我们主要看看module的loaders。loaders是一个数组，里面的每一个对象都用正则表达式，对应着一种配对方案。比如匹配到js后缀名就用babel-loader，匹配到scss后缀名的就先用sass，再用css，最后用style处理，不同的处理器通过 ! 分隔并串联起来。这里的loader是可以省略掉 -loader 这样的，也就是原本应该写成 style-loader!css-loader!sass-loader ，当然我们必须惜字如金，所以都去掉后面的东东。</p>
<p>我们仅仅是配置一下，已经是可以直接用ES2015和SASS去写我们的前端代码了。在此之前，我们对src文件夹里再细分成js，css，image三个文件夹，处理好分层。话不多说，赶紧试试。</p>
<h3 id="稍微复杂的webpack项目"><a href="#稍微复杂的webpack项目" class="headerlink" title="稍微复杂的webpack项目"></a>稍微复杂的webpack项目</h3><h3 id="bebel-loader"><a href="#bebel-loader" class="headerlink" title="bebel-loader"></a>bebel-loader</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">// js/es6-module.js</span><br><span class="line">class People&#123;</span><br><span class="line">  constructor(name)&#123;</span><br><span class="line">    this.name = name;</span><br><span class="line">  &#125;</span><br><span class="line">  sayhi()&#123;</span><br><span class="line">    console.log(`hi $&#123;this.name&#125; !`);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line">exports.module = People;</span><br></pre></td></tr></table></figure>
<p>写好模块后，我们直接在 entry.js 入口文件中引入该模块。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">// entry.js</span><br><span class="line"></span><br><span class="line">// javascript</span><br><span class="line">require(&apos;./js/module1&apos;);</span><br><span class="line">let People = require(&apos;./js/es6-module&apos;);</span><br><span class="line">let p = new People(&quot;Yika&quot;);</span><br><span class="line">p.sayHi();</span><br><span class="line"></span><br><span class="line">// css</span><br><span class="line">require(&apos;./css/main.scss&apos;);</span><br></pre></td></tr></table></figure></p>
<p>哈哈哈，不能再爽！这下子我们可以使用很多优秀的ES6特性去构建大型的web了</p>
<h3 id="sass-loader"><a href="#sass-loader" class="headerlink" title="sass-loader"></a>sass-loader</h3><p>大家或许注意到了下方的css的require，那就是用来加载Sass样式的。我们通过启动style-loader会将css代码转化到 style 标签内，我们看一下里面的内容。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// css/main.scss</span><br><span class="line">html, body&#123;</span><br><span class="line">  background: #dfdfdf;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>最后我们打开 index.html 观察我们所有的结果，首先背景已经是淡灰色的，并且控制台也有我们想要的内容。我们通过查看DOM结构，可以发现 head 标签里多出了 style 标签，里面正是我们想要定制的样式</p>
<h3 id="关于对图片的打包"><a href="#关于对图片的打包" class="headerlink" title="关于对图片的打包"></a>关于对图片的打包</h3><p>我们之前也说，webpack对与静态资源来说，也是看作模块来加载的。CSS我们是已经看过了，那图片是怎么作为模块打包加载进来呢？这里我们可以想到，图片我们是用url-loader加载的。我们在css文件里的url属性，其实就是一种封装处理过require操作。当然我们还有一种方式就是直接对元素的src属性进行require赋值。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">div.img&#123;</span><br><span class="line">  background: url(../image/xxx.jpg)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//或者</span><br><span class="line">var img = document.createElement(&quot;img&quot;);</span><br><span class="line">img.src = require(&quot;../image/xxx.jpg&quot;);</span><br><span class="line">document.body.appendChild(img);</span><br></pre></td></tr></table></figure>
<p>上述两种方法都会对符合要求的图片进行处理。而要求就是在url-loader后面通过query参数的方式实现的，这里就是说只有不大于8kb的图片才会打包处理成Base64的图片。关于query，请看文档： <a href="http://webpack.github.io/docs/using-loaders.html#query-parameters" rel="external" target="_blank">Query parameters</a><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;test: /\.(jpg|png)$/, loader: &quot;url?limit=8192&quot;&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="打包成多个资源文件"><a href="#打包成多个资源文件" class="headerlink" title="打包成多个资源文件"></a>打包成多个资源文件</h3><p>我们在开发多页面的站点的时候，还是需要希望能有多个资源文件的。这样我们就可以有效利用缓存提升性能，做到文件按需加载。如何写入口文件，这里就不再赘述了，我们直接看如何对 webpack.config.js 进行修改。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">// webpack.config.js</span><br><span class="line"></span><br><span class="line">entry: &#123;</span><br><span class="line">  page1: &quot;entry.js&quot;,</span><br><span class="line">  page2: &quot;entry2.js&quot;</span><br><span class="line">&#125;,</span><br><span class="line">output: &#123;</span><br><span class="line">  path: path.join(__dirname, &apos;out&apos;),</span><br><span class="line">    publicPath: &quot;./out/&quot;,</span><br><span class="line">    filename: &apos;[name].js&apos;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>这里重点关注两个地方，entry属性可以是一个对象，而对象名也就是key会作为下面output的filename属性的 [name] 。当然entry也可以是一个数组，更多用法都可以去webpack的 <a href="https://webpack.github.io/docs/" rel="external" target="_blank">官方文档</a> 进行查看。</p>
<p>当然webpack也考虑到公共模块的利用，我们利用插件就可以智能提取公共部分，以提供我们浏览器的缓存复用。我们只需要在 webpack.config.js 添加下面的代码即可。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 修改添加，webpack.config.js</span><br><span class="line">var webpack = require(&apos;webpack&apos;);</span><br><span class="line">module.exports = &#123;</span><br><span class="line">  // ....省略各种代码</span><br><span class="line">      plugins: [</span><br><span class="line">        new webpack.optimize.CommonsChunkPlugin(&apos;common.js&apos;)</span><br><span class="line">      ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>我们做个小测试，让第二个入口文件也加载我们之前的 es6-module.js 。然后我们用webpack进行打包，就发现生成的 common.js 里是有相应代码的。我们需要手动在html上去加载 common.js ，并且是<b> 必须要最先加载</b> 。</p>
<h3 id="独立出css样式"><a href="#独立出css样式" class="headerlink" title="独立出css样式"></a>独立出css样式</h3><p>如果我们希望样式通过 <link> 引入，而不是放在 style 标签内呢，即使这样做会多一个请求。这个时候我们就要配合插件一起使用啦，我们一起来看看。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install extract-text-webpack-plugin --save-dev</span><br></pre></td></tr></table></figure></p>
<p>安装完插件就要配置 webpack.config.js 了。我们添加以下代码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">var ExtractTextPlugin = require(&quot;extract-text-webpack-plugin&quot;);</span><br><span class="line">module.exports = &#123;</span><br><span class="line">  // ...省略各种代码</span><br><span class="line">  module: &#123;</span><br><span class="line">    loaders: [</span><br><span class="line">      &#123;test: /\.js$/, loader: &quot;babel&quot;&#125;,</span><br><span class="line">      &#123;test: /\.css$/, loader: ExtractTextPlugin.extract(&quot;style-loader&quot;, &quot;css-loader&quot;)&#125;,</span><br><span class="line">      &#123;test: /\.(jpg|png|svg)$/, loader: &quot;url?limit=8192&quot;&#125;,</span><br><span class="line">      &#123;test: /\.scss$/, loader: &quot;style!css!sass&quot;&#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;,</span><br><span class="line">  plugins: [</span><br><span class="line">    new webpack.optimize.CommonsChunkPlugin(&apos;common.js&apos;),</span><br><span class="line">    new ExtractTextPlugin(&quot;[name].css&quot;)</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>为了区分开用 <link> 链接和用 style ，我们这里以CSS后缀结尾的模块用插件。我们重点关注一下使用了ExtractTextPlugin的模块，在ExtractTextPlugin的extract方法有两个参数，第一个参数是经过编译后通过style-loader单独提取出文件来，而第二个参数就是用来编译代码的loader。</p>
<p>当然，插件也支持所有独立样式打包成一个css文件。增加多一个参数即可。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">new ExtractTextPlugin(&quot;style.css&quot;, &#123;allChunks: true&#125;)</span><br></pre></td></tr></table></figure></p>
<p>至于怎样加载样式是最佳实践，这个就要自己平时多思考了。多站点多样式的时候，是做到一次性打包加载呢，还是按需加载呢？我这里就建议一项，主页尽量做到最精简，毕竟决定用户存留时间。</p>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>前端社区不断发展，越来越趋向于组件化的发展。通过webpack，我们就能体验到 one component one module 的开发感觉。当然如何更好的使用webpack还是要通过不断的思考总结，才能找到最优的方案。</p>
<h4 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h4><p><a href="http://webpackdoc.com/development.html" target="_blank" rel="external">http://webpackdoc.com/development.html</a><br><a href="https://github.com/webpack/worker-loader" target="_blank" rel="external">https://github.com/webpack/worker-loader</a></p>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        
  <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
    <div>坚持原创技术分享，您的支持将鼓励我继续创作！</div>
    <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
      <span>赏</span>
    </button>
    <div id="QR" style="display: none;">
      
        <div id="wechat" style="display: inline-block">
          <img id="wechat_qr" src="/wechat.jpg" alt="wangyang WeChat Pay"/>
          <p>微信打赏</p>
        </div>
      
      
        <div id="alipay" style="display: inline-block">
          <img id="alipay_qr" src="/alipay.jpg" alt="wangyang Alipay"/>
          <p>支付宝打赏</p>
        </div>
      
    </div>
  </div>


      
    </div>

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/webpack/" rel="tag">#webpack</a>
          
            <a href="/tags/打包工具/" rel="tag">#打包工具</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2016/05/30/移动端适配方案/" rel="next" title="移动端适配方案">
                <i class="fa fa-chevron-left"></i> 移动端适配方案
              </a>
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2016/06/03/GitHub-GitLab-代码结构浏览插件-Octotree/" rel="prev" title="GitHub/GitLab 代码结构浏览插件-Octotree">
                GitHub/GitLab 代码结构浏览插件-Octotree <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
      <div class="ds-thread" data-thread-key="2016/05/30/webpack前端模块加载工具/"
           data-title="webpack前端模块加载工具" data-url="http://html-js.site/2016/05/30/webpack前端模块加载工具/">
      </div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/default_avatar.jpg"
               alt="wangyang" />
          <p class="site-author-name" itemprop="name">wangyang</p>
          <p class="site-description motion-element" itemprop="description">专注于前端</p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">15</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">23</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        
          <div class="feed-link motion-element">
            <a href="/atom.xml" rel="alternate">
              <i class="fa fa-rss"></i>
              RSS
            </a>
          </div>
        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/WangYang-Rex" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  GitHub
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="http://weibo.com/u/2690568063/" target="_blank" title="Weibo">
                  
                    <i class="fa fa-fw fa-weibo"></i>
                  
                  Weibo
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="617418875" target="_blank" title="QQ">
                  
                    <i class="fa fa-fw fa-qq"></i>
                  
                  QQ
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="mailto:617418875@qq.com" target="_blank" title="Mail">
                  
                    <i class="fa fa-fw fa-envelope-o"></i>
                  
                  Mail
                </a>
              </span>
            
          
        </div>

        
        

        
        
          <div class="links-of-blogroll motion-element links-of-blogroll-inline">
            <div class="links-of-blogroll-title">
              <i class="fa  fa-fw fa-globe"></i>
              友链
            </div>
            <ul class="links-of-blogroll-list">
              
                <li class="links-of-blogroll-item">
                  <a href="http://http://moshui.site/" title="moxhuis" target="_blank">moxhuis</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="http://indexof.site/" title="indexof" target="_blank">indexof</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="http://xiaoqiang730730.github.io/" title="xiaoqiang" target="_blank">xiaoqiang</a>
                </li>
              
            </ul>
          </div>
        

      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#为什么用webpack"><span class="nav-number">1.</span> <span class="nav-text">为什么用webpack</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#CommonJs与AMD"><span class="nav-number">2.</span> <span class="nav-text">CommonJs与AMD</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#功能特性"><span class="nav-number">3.</span> <span class="nav-text">功能特性</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#browserify的出现非常棒，但webpack更胜一筹"><span class="nav-number">3.1.</span> <span class="nav-text">browserify的出现非常棒，但webpack更胜一筹</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#开始使用webpack"><span class="nav-number">4.</span> <span class="nav-text">开始使用webpack</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#安装webpack"><span class="nav-number">5.</span> <span class="nav-text">安装webpack</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#一个最简单的webpack"><span class="nav-number">6.</span> <span class="nav-text">一个最简单的webpack</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#webpack配置"><span class="nav-number">6.1.</span> <span class="nav-text">webpack配置</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#编写入口文件"><span class="nav-number">7.</span> <span class="nav-text">编写入口文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#启动webpack"><span class="nav-number">8.</span> <span class="nav-text">启动webpack</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#多模块依赖"><span class="nav-number">9.</span> <span class="nav-text">多模块依赖</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#loader加载器"><span class="nav-number">10.</span> <span class="nav-text">loader加载器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#安装loader"><span class="nav-number">11.</span> <span class="nav-text">安装loader</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#配置loader"><span class="nav-number">12.</span> <span class="nav-text">配置loader</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#稍微复杂的webpack项目"><span class="nav-number">13.</span> <span class="nav-text">稍微复杂的webpack项目</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#bebel-loader"><span class="nav-number">14.</span> <span class="nav-text">bebel-loader</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#sass-loader"><span class="nav-number">15.</span> <span class="nav-text">sass-loader</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#关于对图片的打包"><span class="nav-number">16.</span> <span class="nav-text">关于对图片的打包</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#打包成多个资源文件"><span class="nav-number">17.</span> <span class="nav-text">打包成多个资源文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#独立出css样式"><span class="nav-number">18.</span> <span class="nav-text">独立出css样式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#总结"><span class="nav-number">19.</span> <span class="nav-text">总结</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#参考链接"><span class="nav-number">19.1.</span> <span class="nav-text">参考链接</span></a></li></ol></li></ol></div>
            
          </div>
        </section>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2016</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">wangyang</span>
</div>

<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Pisces
  </a>
</div>

        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.0.1"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.0.1"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.1"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.0.1"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.1"></script>



  

  
    
  

  <script type="text/javascript">
    var duoshuoQuery = {short_name:"html-js"};
    (function() {
      var ds = document.createElement('script');
      ds.type = 'text/javascript';ds.async = true;
      ds.id = 'duoshuo-script';
      ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
      ds.charset = 'UTF-8';
      (document.getElementsByTagName('head')[0]
      || document.getElementsByTagName('body')[0]).appendChild(ds);
    })();
  </script>

  
    
    <script src="/vendors/ua-parser-js/dist/ua-parser.min.js?v=0.7.9"></script>
    <script src="/js/src/hook-duoshuo.js"></script>
  






  
  

  

  

  

</body>
</html>
